package top.yangguangmc.sunshine_anticheat;

import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import top.yangguangmc.sunshine_anticheat.check.Check;
import top.yangguangmc.sunshine_anticheat.check.CheckCategory;
import top.yangguangmc.sunshine_anticheat.utils.Utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.bukkit.ChatColor.*;
import static top.yangguangmc.sunshine_anticheat.utils.Builtin.*;

public class CommandHandler implements TabExecutor {
    public static final String PERMISSION = "sunshineac.cmd";
    private CommandSender theSender;

    CommandHandler() {
    }

    private void sendMessage(String msg) {
        if (theSender == null) return;
        theSender.sendMessage(ssac.getConfigManager().getString("plugin-prefix",
                (theSender instanceof OfflinePlayer ? (OfflinePlayer) theSender : null)).concat(msg));
    }

    private boolean failMessage(String msg) {
        if (msg != null && !msg.trim().isEmpty()) sendMessage(RED + msg);
        return false;
    }

    private boolean successMessage(String msg) {
        if (msg != null && !msg.trim().isEmpty()) sendMessage(GREEN + msg);
        return true;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        theSender = sender;
        if (cmd.getName().equals("sunshineanticheat")) {
            if (!(sender.hasPermission(PERMISSION + ".*") || sender.hasPermission(PERMISSION))) {
                sender.sendMessage(RESET + ssac.getConfigManager().getString("no-permission-msg"));
                return true;
            }
            if (args.length == 0) {
                sendMessage(GOLD + SunshineAntiCheat.NAME
                        + GRAY + " v" + GREEN + SunshineAntiCheat.VERSION
                        + GRAY + " by " + YELLOW + SunshineAntiCheat.AUTHOR);
                sendMessage("Type '/ssac help' for help!");
                return true;
            }
            if (args[0].equalsIgnoreCase("alert")) {
                if (args.length == 1) {
                    if (!(sender instanceof Player)) {
                        failMessage("Only players can perform this command!");
                        return true;
                    }
                    Player player = (Player) sender;
                    if (player.hasPermission(AlertManager.PERMISSION)) {
                        ssac.getAlertManager().toggleAlert(player);
                        return successMessage("Successfully set your alert to "
                                + (ssac.getAlertManager().isAlertEnabled(player) ? "enabled" : "disabled"));
                    } else return failMessage("You don't have the permission!");
                } else {
                    Player player = Bukkit.getPlayer(args[1]);
                    if (player != null) {
                        if (player.hasPermission(AlertManager.PERMISSION)) {
                            ssac.getAlertManager().toggleAlert(player);
                            return successMessage("Successfully set " + player.getName() + "'s alert to "
                                    + (ssac.getAlertManager().isAlertEnabled(player) ? "enabled" : "disabled"));
                        } else
                            return failMessage("Player " + player.getName()
                                    + " didn't have permission " + AlertManager.PERMISSION + "!");
                    } else return failMessage("No such player with name " + args[1]);
                }
            } else if (args[0].equalsIgnoreCase("help")) {
                printHelp();
                return true;
            } else if (args[0].equalsIgnoreCase("reload")) {
                ssac.getConfigManager().load();
                return successMessage("Config reloaded!");
            } else if (args[0].equalsIgnoreCase("resetconfig")) {
                boolean success = ssac.getConfigManager().resetConfig();
                if (!success) {
                    logger.severe("Cannot delete config file at "
                            + ssac.getConfigManager().getFile().getAbsolutePath() + "!");
                    return failMessage("Failed to delete config file!");
                } else return successMessage("Config reset!");
            } else if (args[0].equalsIgnoreCase("violations")) {
                if (args.length < 2) return failMessage("Please enter a player name! " +
                        "Usage: /ssac violations <Player> -> Queries a player's violations.");
                String name = args[1];
                if (Bukkit.getPlayer(name) == null) return failMessage("The player isn't online.");
                sendMessage(RED + "Violations for " + GOLD + name + RED + ":");
                for (CheckCategory category : CheckCategory.values()) {
                    sendMessage(RED + category.getDisplayName() + ":");
                    int totalVL = 0;
                    for (Check check : ssac.getCheckManager().getChecksByCategory(category)) {
                        int vl = check.getViolation(Bukkit.getPlayer(name));
                        if (vl <= 0) continue;
                        totalVL += vl;
                        sendMessage(RED + check.getCheckName() + GRAY + ": " + WHITE + vl);
                    }
                    sendMessage(RED + "* Total VL: " + WHITE + totalVL);
                }
                return true;
            } else if (args[0].equalsIgnoreCase("resetvl")) {
                if (args.length == 1) {
                    ssac.getCheckManager().resetVl();
                    return successMessage("Violations for all online players has been reset!");
                } else {
                    String name = args[1];
                    if (Bukkit.getPlayer(name) == null) return failMessage("The player isn't online.");
                    ssac.getCheckManager().resetVl(name);
                    return successMessage("Violations for " + name + " has been reset!");
                }
            } else if (args[0].equalsIgnoreCase("test")) {
                String commandLine = Utils.preprocessString("kick %player% [SSAC] test message!", Bukkit.getPlayer("yangguangMC"));
                Bukkit.dispatchCommand(Bukkit.getConsoleSender(), commandLine);
                return successMessage("Performed test command!");
            } else return failMessage("Unknown subcommand: " + args[0] + ". Type \"/ssac help\" for help.");
        } else return failMessage("Unregistered command \"" + cmd.getName() + "\"!");
    }

    @Override
    public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
        theSender = sender;
        if (!(theSender instanceof Player)) return null;
        if (!sender.hasPermission("sunshineac.cmd")) return null;
        if (args.length <= 1) {
            return Arrays.asList("alert", "help", "reload", "resetconfig", "resetvl", "violations");
        } else if (args.length == 2) {
            if (args[0].equalsIgnoreCase("violations") || args[0].equalsIgnoreCase("resetvl")
                    || args[0].equalsIgnoreCase("alert")) {
                List<String> names = new ArrayList<>(Bukkit.getOnlinePlayers().size());
                for (Player player : Bukkit.getOnlinePlayers()) {
                    names.add(player.getName());
                }
                names.sort(null);
                return names;
            }
        }
        return null;
    }

    private void printHelp() {
        sendMessage("/ssac " + AQUA + "alert" + GRAY + " -> " + WHITE + "Toggles your alert.");
        sendMessage("/ssac " + AQUA + "alert [Player Name]" + GRAY + " -> " + WHITE + "Toggles the specific player's alert.");
        sendMessage("/ssac " + AQUA + "help" + GRAY + " -> " + WHITE + "Shows the help menu.");
        sendMessage("/ssac " + AQUA + "reload" + GRAY + " -> " + WHITE + "Reloads the config from the disk.");
        sendMessage("/ssac " + AQUA + "resetconfig" + GRAY + " -> " + WHITE + "Resets the config file in the disk.");
        sendMessage("/ssac " + AQUA + "resetvl" + GRAY + " -> " + WHITE + "Resets the violations for all the online players.");
        sendMessage("/ssac " + AQUA + "resetvl [Player Name]" + GRAY + " -> " + WHITE + "Resets the violations for the specific player.");
        sendMessage("/ssac " + AQUA + "violations <Player Name>" + GRAY + " -> " + WHITE + "Shows the violations for the specific player.");

    }
}
